﻿using System;

namespace Aeon.Framework
{

/// <summary>
/// Value object for two dimensional vector representation.
/// 
/// </summary>
public struct VectorP : IVector
    {
    // --- Attributes:

    private Double rad;     // Vector length.
    private Double theta;   // Vector slope.

    // --- Properties:

    public Single X { get { return(GetCartesian().X); } }
    public Single Y { get { return(GetCartesian().Y); } }
    public Single Z { get { return(0); } }

    public Double R { get { return(rad); } }
    public Double T { get { return(theta); } }

    // --- Constructor:

    /// <summary>
    /// Create vector from cartesian 2D coordinates.
    /// 
    /// </summary>
    /// <param name="x"> X plane component. </param>
    /// <param name="y"> Y plane component. </param>
    public VectorP(Single x, Single y)
        {
        rad = Math.Sqrt(Math.Pow(x,2) + Math.Pow(y,2));

        if (x == 0 && y == 0) theta = 0;
        
        if (x >= 0) { theta = 1/Math.Sin(y/rad); }
        else { theta = -(1/Math.Sin(y/rad)) + Math.PI; }
        }

    /// <summary>
    /// Create vector from polar coordinates.
    /// 
    /// </summary>
    /// <param name="radius"> Vector length. </param>
    /// <param name="radians"> Vector angle, in Pi Radians. </param>
    public VectorP(Double radius, Double radians)
        {
        rad = radius;
        theta = radians;
        }

    // --- Public Methods:

    /// <summary>
    /// Transforms this vector into a unit vector.
    /// 
    /// </summary>
    public void ToUnit()
        {

        rad = 1;
        }

    /// <summary>
    /// Returns the unitary component of this vector.
    /// 
    /// </summary>
    public IVector GetUnit() 
        { 

        return(new VectorP(1,theta)); 
        }

    /// <summary>
    /// Returns the perpendicular normal to this vector.
    /// 
    /// </summary>
    public IVector GetNormal()
        {

        return(new VectorP(rad,theta+Math.PI/2));
        }

    /// <summary>
    /// Returns the 3D cartesian representation of this vector.
    /// 
    /// </summary>
    public IVector GetCartesian()
        {
        Single x = (float)(rad*Math.Cos(theta));
        Single y = (float)(rad*Math.Sin(theta));

        return(new VectorC(x,y));
        }

    /// <summary>
    /// Returns the 2D polar representation of this vector.
    /// 
    /// </summary>
    public IVector GetPolar()
        {

        return(this);
        }
    }


}
